 @include "lib.awk"
 BEGIN { CohensRule=0.3 }
 function keyValues(bins,bins2,sorter,    bins1,sum,n,b,x) {
   for(b in bins) {
     bins1[b]["key"]=b
     sum=n=0
     for(x in bins[b]) {
       n++
       sum += (bins1[b]["val"][x] = bins[b][x])
     }
     bins1[b]["mean"] = sum/n
   }
   return asort(bins1, bins2,sorter ? sorter : "meanAsc")
 }
 function meanAsc(a,x,b,y) { 
   return x["mean"] - y["mean"] 
 }
 function binchop(bins,bins1,     sorter,\
                   overall,m,b,x,val,s,sq,n,sL,sqL,nL,sR,sqR,nR) {
   m = keyValues(bins,bins1,sorter)
   if (m==1)
     return bins[1]["bin"] = 1
   for(b=1; b<= m; b++)
     for(x in bins1[b]["val"]) {
       val = bins1[b]["val"][x]
       s += val; sq += val*val; n++
       sL[b] = s  ; sqL[b] = sq; nL[b] = n
     }
   for(b=1; b< m; b++) {
      sR[b]= sL[m - b]; sqR[b] = sqL[m - b]; nR[b]=nL[m - b]
   }
   sR[m] = sqR[m] = nR[m] = 0
   o(nL,"nl") o(nR,"nR")
   overall = sd(nL[m],sL[m],sqL[m])
   binchop1(bins1,"",1,m,1,overall,sL,sqL,nL,sR,sqR,nR)
 } 
 
 function binchop1(bins,indent,lo,hi,id,best,sL,sqL,nL,sR,sqR,nR, \
                    n1,s1,sq1,sd1,n0,s0,sq0,n3,s3,sq3,\
                    n2,s2,sq2,sd2,b,tmp,cut,effectSize,before) {
   before= best
   print indent "lo " lo " hi " hi " id " id
   if (lo >= hi ) { 
     return bins[lo]["bin"] = id 
   }
   n0 = s0 = sq0 = n3 = s3 = sq3 = 0
   if ((lo - 1) in sL) { n0 = nL[lo-1]; s0= sL[lo-1]; sq0= sqL[lo-1] } 
   if ((hi + 1) in sR) { n3 = nR[hi+1]; s3= sR[hi+1]; sq3= sqR[hi+1] } 
   for(b=lo; b<hi; b++) {
     n1= nL[b]-n0; s1= sL[b]-s0; sq1= sqL[b]-sq0; 
     n2= nR[b]-n3; s2= sR[b]-s3; sq2= sqR[b]-sq3; 
     sd1=sd(n1,s1,sq1); sd2=sd(n2,s2,sq2);
     tmp = n1/(n1+n2) * sd1 + n2/(n1+n2) * sd2
     effectSize = abs(s1/n1 - s2/n2)/best
     print indent "lo " lo " hi " hi " b " b " key " bins[b]["key"] " nL " nL[b] " nR " nR[b] " n1 " n1 \
           " n2 " n2 " sd1 " sd1 " sd2 " sd2 " tmp " tmp " best " best " effectSize " effectSize
     if (tmp < best && effectSize > CohensRule) {
       best = tmp
       cut  = b
     }}
   if (cut) {
     print "new " lo " to " cut " then " cut+1 " to " hi
     id = 1 + binchop1(bins,"   | " indent, lo,   cut,id,best,sL,sqL,nL,sR,sqR,nR)
     id =     binchop1(bins,"   | " indent,cut+1, hi,id,best,sR,sqR,nR,sR,sqR,nR)
   } else 
     for(b=lo; b<=hi; b++) bins[b]["bin"] = id
   return id
}
   
